package com.om.example.loginservice;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static org.mockito.Mockito.*;


public class LoginServiceTest {

	   @Mock private IAccount account;
	   private IAccountRepository accountRepository;
	   private LoginService service;
	 
	   @Before
	   public void init() {
	     // account = mock(IAccount.class);
		  MockitoAnnotations.initMocks(this);
	      accountRepository = mock(IAccountRepository.class);
	      when(accountRepository.find(anyString())).thenReturn(account);
	      service = new LoginService(accountRepository);
	   }
	 
	   private void willPasswordMatch(boolean value) {
	      when(account.passwordMatches(anyString())).thenReturn(value);
	   }
	 
	   @Test
	   public void itShouldSetAccountToLoggedInWhenPasswordMatches() {
	      willPasswordMatch(true);
	      service.login("brett", "password");
	      verify(account, times(1)).setLoggedIn(true);
	   }
	 
	   @Test
	   public void itShouldSetAccountToRevokedAfterThreeFailedLoginAttempts() {
	      willPasswordMatch(false);
	 
	      for (int i = 0; i < 3; ++i)
	         service.login("brett", "password");
	 
	      verify(account, times(1)).setRevoked(true);
	   }
	   
	   @Test
	   public void itShouldNotSetAccountLoggedInIfPasswordDoesNotMatch() {
	      willPasswordMatch(false);
	      service.login("brett", "password");
	      verify(account, never()).setLoggedIn(true);
	   }
	   
	   @Test
	   public void itShouldNotRevokeSecondAccountAfterTwoFailedAttemptsFirstAccount() {
	      willPasswordMatch(false);
	 
	      IAccount secondAccount = mock(IAccount.class);
	      when(secondAccount.passwordMatches(anyString())).thenReturn(false);
	      when(accountRepository.find("schuchert")).thenReturn(secondAccount);
	 
	      service.login("brett", "password");
	      service.login("brett", "password");
	      service.login("schuchert", "password");
	 
	      verify(secondAccount, never()).setRevoked(true);
	   }
	   
	   @Test(expected = AccountNotFoundException.class)
	   public void ItShouldThrowExceptionIfAccountNotFound() {
	      when(accountRepository.find("schuchert")).thenReturn(null);
	      service.login("schuchert", "password");
	   }
	   
	   @Test(expected = AccountRevokedException.class)
	   public void ItShouldNotBePossibleToLogIntoRevokedAccount() {
	      willPasswordMatch(true);
	      when(account.isRevoked()).thenReturn(true);
	      service.login("brett", "password");
	   }
	   
	 
	 
}
